# -*- coding:utf-8 -*-

import asyncore
import ldap
import logging
import socket
import signal
import sys
from threading import Thread
import os
from re import search
import logging
import optparse

import ldap_worker


class ConnectionsHandler( asyncore.dispatcher_with_send ):
    
    def __init__( self, conn_sock ):
        asyncore.dispatcher_with_send.__init__(self, conn_sock)

    def handle_read(self):
        data = self.recv(40)
        if (len(data) > 0):
            logging.debug("se reciben datos: %s" 
                          %(data))
            #TODO: comprobar que existe el usuario
            self.change_ldap_homedir(data)
    
    def change_ldap_homedir(self, user, revert=False):
        ldap_w = ldap_worker.LDAP_Worker('f0', user)
        ldap_w.migrate_to_fijo()
    

class ConnectionsDispatcher(Thread, asyncore.dispatcher):
    
    def __init__(self, port=30000):
        asyncore.dispatcher.__init__( self )
        Thread.__init__(self)
        
        self.port = port
        
        
    ## Se inicializa la escucha en el puerto que se establece en el constructor
    # Es aquí donde se lanza el asyncore.lopp()
    def run( self ):
        logging.info("Thread created and running on port: %s" %self.port)
        self.create_socket(socket.AF_INET6, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind(('',self.port))
        self.listen(5)
        self.connection_handler = None
        asyncore.loop()
    
    
    ## Método que se ejecuta al realizarse una conexión
    #
    def handle_accept(self):
        logging.info('incoming connection')
        pair = self.accept()
        if pair is None:
            pass
        else:
            sock, addr = pair
            logging.debug( 'accepted connection from %s:%s' 
                            %(repr(sock), repr(addr)))
            self.connection_handler = ConnectionsHandler(sock)
        return True
    
    def close_connections(self, signal, frame):
        logging.debug("signal received: %s" %signal)
        sys.exit(0)
        

if __name__ == "__main__":
    
    parser = optparse.OptionParser()
    parser.add_option( '--debug', help='start in debug mode, NO DAEMONIZE',
                       dest="debug", action="store_true", default=False)
    (options, args) = parser.parse_args()
    
    if options.debug:
        logging.basicConfig(level=logging.DEBUG,
                            format="%(asctime)s %(filename)s: %(funcName)s - %(levelname)s: %(message)s")
        logging.debug("debug mode: ON")
    else:
        logging.basicConfig(level=logging.DEBUG,
                            filename="./log",
                            format="%(asctime)s %(filename)s: %(funcName)s - %(levelname)s: %(message)s")
    
    file_pid = "file_pid"
    in_proc = '/proc/%s' %(file_pid)
    if os.path.isfile(file_pid) and os.path.exists(in_proc):
        logging.info("el demonio ya está corriendo!")
        sys.exit(0)
    
    ps = ConnectionsDispatcher()
    signal.signal(signal.SIGINT,ps.close_connections)
    
    if options.debug:
        ps.start()
    else:
        pid = os.fork()
        if pid==0:
            #HIJITO BONITO! 
            with open(file_pid, 'w') as f:
                f.write(str(os.getpid()))
            ps.start()
        else:
            #PAPIIITO AL CAJÓN †
            sys.exit(0)
        

